package util;
import java.util.*;
import data.*;
import java.io.*;
import java.net.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;

import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.rdf.*;
import com.hp.hpl.jena.tdb.*;
import com.hp.hpl.jena.vocabulary.*;


public class RDFPublisher {
	public static void publishData(ArrayList<RecipeData> recipes, ArrayList<CheeseData> cheeses){
		
		// Direct way: Make a TDB-backed Jena model in the named directory.
		  String directory = "/Users/philliptischler/Documents/PMT/Work/school/sophmore/CS4302/googleCode/cs4302-2011sp/PerfectPairing/MyDatabases/PerfectPairing" ;
		  Model model = TDBFactory.createModel(directory);
		  
		  String nsPP = "http://www.semanticweb.org/ontologies/ontology/2011/4/PerfectPairing.owl/";
		  String nsRDFS = "http://www.w3.org/2000/01/rdf-schema";
		  String nsOWL = "http://www.w3.org/2002/07/owl";
		  String nsRDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns";
		  
		  //object properties
		  Property hasBody = model.getProperty(nsPP, "hasBody");
		  Property hasIngredient = model.getProperty(nsPP, "hasIngredient");
		  Property hasVarietal = model.getProperty(nsPP, "hasVarietal");
		  //inverse object properties
		  Property hasWine = model.getProperty(nsPP, "hasWine");
		  Property hasWinery = model.getProperty(nsPP, "hasWinery");
		  Property fromRegion = model.getProperty(nsPP, "fromRegion");
		  Property regionProduces = model.getProperty(nsPP, "regionProduces");
		  Property pairsWith = model.getProperty(nsPP,"pairsWith");
		  
		  Property hasDescription = model.getProperty(nsPP, "hasDescription");
		  Property hasImageURL = model.getProperty(nsPP, "hasImageURL");
		  Property hasName = model.getProperty(nsPP, "hasName");
		  Property hasPrice = model.getProperty(nsPP, "hasPrice");
		  Property hasRating = model.getProperty(nsPP, "hasRating");
		  Property hasURL = model.getProperty(nsPP, "hasURL");
		  Property hasVintage = model.getProperty(nsPP, "hasVintage");
		  
		  Property type = RDF.type;
		  
		  Resource wineType = getResource(model,formURI(nsPP,"Wine"));
		  Resource cheeseType = getResource(model,formURI(nsPP,"Cheese"));
		  Resource regionType = getResource(model,formURI(nsPP,"Region"));
		  Resource recipeType = getResource(model,formURI(nsPP,"Recipe"));
		  Resource ingredientType = getResource(model,formURI(nsPP,"Ingredient"));
		  Resource varietalType = getResource(model,formURI(nsPP,"Varietal"));
		  Resource wineryType = getResource(model,formURI(nsPP,"Winery"));

		  for(int i = 0; i < cheeses.size(); i++){
			  CheeseData cur = cheeses.get(i);
			  if(!stringOK(cur.getName()))
				  continue;
			  Resource cheese = getResource(model,formURI(nsPP,cur.getName().replace(" ", "_").toLowerCase()));
			  model.add(model.createStatement(cheese,type,cheeseType));
			  if(stringOK(cur.getRegion())){
				  Resource region = getResource(model,formURI(nsPP,cur.getRegion()));
				  model.add(model.createStatement(region,type,regionType));
				  model.add(model.createStatement(cheese,fromRegion,region));
				  model.add(model.createStatement(region,hasIngredient,cheese));
			  }
			  if(stringOK(cur.getDescrip()))
				  model.add(model.createStatement(cheese,hasDescription,cur.getDescrip()));
			  if(stringOK(cur.getName()))
				  model.add(model.createStatement(cheese,hasName,cur.getName()));
		  }
		  
		  for(int i = 0; i < recipes.size(); i++){
			  RecipeData cur = recipes.get(i);
			  if(!stringOK(cur.getHref()))
				  continue;
			  Resource recipe = getResource(model,cur.getHref());
			  model.add(model.createStatement(recipe,type,recipeType));
			  
			  String[] ingredients = cur.getIngredients().split(",");
			  for(int j = 0; j < ingredients.length; j++){
				  if(!stringOK(ingredients[j]))
					  continue;
				  Resource ingred = getResource(model,formURI(nsPP,ingredients[j].replace(" ","_").toLowerCase()));
				  model.add(model.createStatement(ingred,type,ingredientType));
				  
				  model.add(model.createStatement(ingred,hasName,ingredients[j]));
				  model.add(model.createStatement(recipe,hasIngredient,ingred));
			  }
			  if(stringOK(cur.getTitle()))
				  model.add(model.createStatement(recipe,hasName,cur.getTitle()));
			  
			  ArrayList<Varietal> varietals = cur.getVarietals();
			  ArrayList<WineData> wines = cur.getWines();
			  for(int j = 0; j < varietals.size(); j++){
				  if(!stringOK(varietals.get(j).getVarietal()))
					  continue;
				  Resource varietal = getResource(model,formURI(nsPP,varietals.get(j).getVarietal()));
				  model.add(model.createStatement(varietal,type,varietal));
				  
				  model.add(model.createStatement(varietal,hasName,varietals.get(j).getVarietal()));
				  if(stringOK(varietals.get(j).getType()))
					  model.add(model.createStatement(varietal,hasDescription,varietals.get(j).getType()));
				  
				  model.add(model.createStatement(recipe,hasVarietal,varietal));
			  }
			  
			  for(int j = 0; j < wines.size(); j++){
				  WineData curW = wines.get(j);
				  Resource wine = getResource(model,curW.getUrl());
				  model.add(model.createStatement(wine,type,wineType));
				  
				  model.add(model.createStatement(wine,pairsWith,recipe));
				  model.add(model.createStatement(recipe,pairsWith,wine));
				  
				  if(stringOK(curW.getWinery())){
					  Resource winery = getResource(model,formURI(nsPP,curW.getWinery()));
					  model.add(model.createStatement(winery,type,wineryType));
					  model.add(model.createStatement(wine,hasWinery,winery));
					  model.add(model.createStatement(winery,hasWine,wine));
				  }
				  
				  if(stringOK(curW.getRegion())){
					  Resource region = getResource(model,formURI(nsPP,curW.getRegion().split(">")[0].split("&gt")[0].trim()));
					  model.add(model.createStatement(region,type,regionType));
					  model.add(model.createStatement(wine,fromRegion,region));
					  model.add(model.createStatement(region,regionProduces,wine));
				  }
				  
				  if(stringOK(curW.getVarietal())){
					  Resource varietal = getResource(model,formURI(nsPP,curW.getVarietal()));
					  model.add(model.createStatement(varietal,type,varietalType));
					  model.add(model.createStatement(wine,hasVarietal,varietal));
				  }
				  
				  if(stringOK(curW.getDescrip()))
					  model.add(model.createStatement(wine,hasDescription,curW.getDescrip()));
				  if(stringOK(curW.getImageURL()))
					  model.add(model.createStatement(wine,hasImageURL,curW.getImageURL()));
				  if(stringOK(curW.getName()))
					  model.add(model.createStatement(wine,hasName,curW.getName()));
				  model.add(model.createStatement(wine,hasPrice,model.createTypedLiteral(curW.getPrice(),XSDDatatype.XSDdouble)));
				  model.add(model.createStatement(wine,hasRating,model.createTypedLiteral(curW.getRating(),XSDDatatype.XSDdouble)));
				  if(stringOK(curW.getUrl()))
					  model.add(model.createStatement(wine,hasURL,curW.getUrl()));
				  if(stringOK(curW.getVintage()))
					  model.add(model.createStatement(wine,hasVintage,curW.getVintage()));
				  
				  model.add(model.createStatement(recipe,hasWine,wine));
			  }

			  
		  }
		  
		  StmtIterator it = model.listStatements();
		  while(it.hasNext()){
			  System.out.println(it.next().toString());
		  }
		  System.out.println(model.toString());
		  
		  model.close();
	}
	
	public static boolean stringOK(String val){
		return val != null && !val.equals("");
	}
	
	public static String formURI(String ns, String name){
		return ns + name;
	}
	
	public static Resource getResource(Model mod, String uri){
		Resource r = mod.getResource(uri);
		if(r == null)
			r = mod.createResource(uri);
		return r;
	}
	
}
